<template>
  <div :tabindex="disabled ? null : 0" :class="classes" @mouseleave="handleMouseleave"
       @keydown.left.stop.prevent="decrease"
       @keydown.right.stop.prevent="increase">
    <div
      v-for="item in field.count"
      :class="starCls(item)"
      @mousemove="handleMousemove(item, $event)"
      @click="handleClick(item)">
      <span :class="[prefixCls + '-star-content']" type="half"></span>
    </div>
    <div :class="[prefixCls + '-text']" v-if="field.showText" v-show="currentValue > 0">
      <slot>
        <span>{{ currentValue }}</span>
        <span v-if="currentValue <= 1">{{ lang('i.rate.star') }}</span>
        <span v-else>{{ lang('i.rate.stars') }}</span>
      </slot>
    </div>
  </div>
</template>
<script>
  import Locale from '../locales/mixin'

  let prefixCls = 'va-df-rate'

  /*
  * field配置
  *   count: int
  *   allowHalf: boolean
  *   showText: string
  * */
  export default {
    mixins: [Locale],
    props: {
      field: {
        type: Object,
        default () {
          return {}
        }
      },
      disabled: {
        type: Boolean,
        default: false
      },
      value: {
        type: Number,
        default: 0
      },
      name: {
        type: String
      }
    },
    data () {
      return {
        prefixCls: prefixCls,
        hoverIndex: -1,
        isHover: false,
        isHalf: this.field.allowHalf,
        currentValue: 0
      }
    },
    mounted () {
      this.currentValue = this.value || 0
    },
    computed: {
      classes () {
        return [
          `${prefixCls}`,
          {
            [`${prefixCls}-disabled`]: this.disabled
          }
        ]
      }
    },
    watch: {
      value (val) {
        this.currentValue = val
      },
      currentValue (val) {
        this.setHalf(val)
      }
    },
    methods: {
      starCls (value) {
        const hoverIndex = this.hoverIndex
        const currentIndex = this.isHover ? hoverIndex : this.currentValue

        let full = false
        let isLast = false

        if (currentIndex >= value) full = true

        if (this.isHover) {
          isLast = currentIndex === value
        } else {
          isLast = Math.ceil(this.currentValue) === value
        }

        return [
          `${prefixCls}-star`,
          {
            [`${prefixCls}-star-full`]: (!isLast && full) || (isLast && !this.isHalf),
            [`${prefixCls}-star-half`]: isLast && this.isHalf,
            [`${prefixCls}-star-zero`]: !full
          }
        ]
      },
      handleMousemove (value, event) {
        if (this.disabled) return

        this.isHover = true
        if (this.field.allowHalf) {
          const type = event.target.getAttribute('type') || false
          this.isHalf = type === 'half'
        } else {
          this.isHalf = false
        }
        this.hoverIndex = value
      },
      handleMouseleave () {
        if (this.disabled) return

        this.isHover = false
        this.setHalf(this.currentValue)
        this.hoverIndex = -1
      },
      setHalf (val) {
        val = +val || 0
        this.isHalf = this.field.allowHalf && val.toString().indexOf('.') >= 0
      },
      handleClick (value) {
        if (this.disabled) return
        if (this.isHalf) value -= 0.5
        this.currentValue = value
        this.$emit('input', value)
      },
      decrease () {
        if (this.disabled || this.currentValue === 0) return
        this.$emit('input', this.field.allowHalf ? this.currentValue - 0.5 : this.currentValue - 1)
      },
      increase () {
        if (this.disabled || this.currentValue === this.field.count) return
        this.$emit('input', this.field.allowHalf ? this.currentValue + 0.5 : this.currentValue + 1)
      }
    }
  }
</script>
